package com.haiqiu.busines.service.impl;

import com.haiqiu.busines.entity.SysFile;
import com.haiqiu.busines.mapper.FileMaper;
import com.haiqiu.busines.service.SysFileService;
import com.haiqiu.common.entity.FileServer;
import com.haiqiu.common.exception.BaseException;
import com.haiqiu.common.page.PageRequest;
import com.haiqiu.common.page.PageResponse;
import com.haiqiu.common.result.Constants;
import com.haiqiu.common.utils.files.FtpUtil;
import com.haiqiu.common.utils.files.OssUtil;
import com.haiqiu.common.utils.files.ServerFileUtil;
import com.haiqiu.common.utils.files.UploadUtil;
import com.haiqiu.common.utils.tools.StringUtil;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * @author: HaiQiu
 * @Date: 2021/4/6
 * @Description: 公告逻辑层
 */
@Service
public class SysFileServiceImpl implements SysFileService {

    @Autowired
    private FileMaper fileMaper;

    @Autowired
    private FtpUtil ftpUtil;

    @Autowired
    private OssUtil ossUtil;

    @Autowired
    private ServerFileUtil serverFileUtil;

    @Autowired
    private UploadUtil uploadUtil;

    @Value("${oss.theme}")
    private String systemPath;

    /**
     * 资源文件父路径
     */
    @Value("${http.parent:/root}")
    private String parent;

    /**
     * 根据ID删除数据
     *
     * @param id 数据ID
     */
    @Override
    public void deleteByPrimaryKey(Long id) {
        if (StringUtils.isEmpty(id)) {
            throw new BaseException(Constants.ID_EXITS);
        }
        if (fileMaper.deleteByPrimaryKey(id) == 0) {
            throw new BaseException(Constants.FAIL_DEL);
        }
    }


    @Override
    public void insert(SysFile sysFile) {
        if (!StringUtils.isEmpty(sysFile.getPath())) {
            String[] split = sysFile.getPath().split("/");
            String fileName = split[split.length - 1];
            if (StringUtils.isEmpty(sysFile.getTitle())) {
                sysFile.setTitle(fileName);
            }
            sysFile.setCreateTime(new Date());
            sysFile.setUpdateTime(new Date());
            if (fileMaper.insert(sysFile) == 0) {
                throw new BaseException(Constants.FAIL_ADD);
            }
        } else {
            throw new BaseException("未检测到可用的文件url地址");
        }

    }


    /**
     * 根据ID查询
     *
     * @param id 数据ID
     * @return 公告实体
     */
    @Override
    public SysFile selectByPrimaryKey(Long id) {
        SysFile sysFile = fileMaper.selectByPrimaryKey(id);
        if (sysFile == null) {
            throw new BaseException(Constants.DATA_EXIT);
        }
        return sysFile;
    }


    @Override
    public void updateByPrimaryKeySelective(SysFile sysFile) {
        sysFile.setUpdateTime(new Date());
        if (fileMaper.updateByPrimaryKeySelective(sysFile) == 0) {
            throw new BaseException(Constants.FAIL_UPDATE);
        }
    }


    @Override
    public int delBatch(Set<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new BaseException(Constants.ID_EXITS);
        }
        for (Long id : ids) {
            SysFile sysFile = fileMaper.selectByPrimaryKey(id);
            if (sysFile != null) {
                serverFileUtil.delete(sysFile.getPath());
            }
        }
        int i = fileMaper.batchDel(ids);
        if (i == 0) {
            throw new BaseException(Constants.FAIL_DEL);
        }
        return i;
    }


    /**
     * 分页模糊查询
     *
     * @param request 查询实体（包含分页）
     * @return 返回分页数据
     */
    @Override
    public PageResponse<SysFile> list(PageRequest<SysFile> request) {
        SysFile sysFile = StringUtil.checkObjFieldIsNull(request.getParams());
        long count = fileMaper.count(sysFile);
        PageResponse<SysFile> response = new PageResponse<>();
        response.setPageSize(request.getPageSize());
        response.setTotal(count);
        response.setPageIndex(request.getPageIndex());
        if (count > 0) {
            List<SysFile> list = fileMaper.page(sysFile, request.getOffset(), request.getPageSize());
            response.setData(list);
        }
        return response;
    }


    @Override
    public List<SysFile> all() {
        return fileMaper.all();
    }


    @Override
    public String upload(MultipartFile file, String mode, String folder) {
        String url = uploadUtil.upload(file, mode, folder);
        return url;
    }

    @Override
    public List<String> uploadFile(List<MultipartFile> files, SysFile sysFileModel) {
        //检查文件是否为空
        checkFiles(files);
        try {
            List<String> urlList = new ArrayList<>();
            for (MultipartFile file : files) {
                String url = ftpUtil.uploadFile(file, sysFileModel.getFolder());
                urlList.add(url);
                //是否保存数据库
                if (sysFileModel.getIsSave() != null && sysFileModel.getIsSave()) {
                    saveFileBySql(file, sysFileModel, url);
                }
            }
            return urlList;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void downloadFile(String filePath) {
        serverFileUtil.download(filePath);
    }

    @Override
    public List<FTPFile> show(String folder) {
        return ftpUtil.showFolder(folder);
    }

    @Override
    public void uploadResourceFile(MultipartFile file, SysFile sysFileEntity) {
        try {
            String url = ftpUtil.uploadFile(file, sysFileEntity.getFolder());
            //保存到数据库
            saveFileBySql(file, sysFileEntity, url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 保存文件到数据库
     *
     * @param file          文件
     * @param sysFileEntity 文件信息
     * @param url           url地址
     */
    private void saveFileBySql(MultipartFile file, SysFile sysFileEntity, String url) {
        sysFileEntity.setType(file.getContentType());
        if (StringUtils.isEmpty(sysFileEntity.getTitle())) {
            sysFileEntity.setTitle(file.getOriginalFilename());
        }
        if (StringUtils.isEmpty(sysFileEntity.getFileFlag())) {
            sysFileEntity.setFileFlag("无标签");
        }
        sysFileEntity.setSize(getFileSize(file.getSize()));
        sysFileEntity.setPath(url);
        sysFileEntity.setCreateTime(new Date());
        sysFileEntity.setUpdateTime(new Date());
        fileMaper.insert(sysFileEntity);
    }

    @Override
    public List<Map<String, String>> allFlag(String type) {
        return fileMaper.allFlag(type);
    }

    @Override
    public List<String> serverUpload(List<MultipartFile> files, SysFile sysFileModel) {
        //检查文件是否为空
        checkFiles(files);
        List<String> listPath = new ArrayList<>();
        for (MultipartFile file : files) {
            String url = serverFileUtil.upload(file, sysFileModel.getFolder());
            listPath.add(url);
            //是否保存数据库
            if (sysFileModel.getIsSave() != null && sysFileModel.getIsSave()) {
                saveFileBySql(file, sysFileModel, url);
            }
        }
        return listPath;
    }

    @Override
    public void delFile(String fileUrl) {
        serverFileUtil.deleteFile(fileUrl);
    }

    @Override
    public String uploadTheme(MultipartFile file) {
        return uploadUtil.upload(file, Constants.SERVER, systemPath);
    }

    @Override
    public List<FileServer> serverFileList(String folder, String name, String sort) {
        folder = StringUtils.isEmpty(folder) || !folder.contains(parent) ?  parent : folder;
        name = StringUtils.isEmpty(name) ? null : name;
        return serverFileUtil.getFiles(folder,name,sort);
    }

    @Override
    public int deleteFiles(Set<String> filePaths) {
        int i = serverFileUtil.deleteFiles(filePaths);
        if (i==0){
            throw new BaseException("删除失败");
        }
        return i;
    }

    @Override
    public void addFolder(String folders) {
        if (!serverFileUtil.addFolder(folders)){
         throw new BaseException("创建文件夹失败");
        }
    }

    @Override
    public void serverRename(String filePath, String newName, String parentPath) {
        if (StringUtils.isEmpty(filePath)){
            throw new BaseException("源文件路径不能为空");
        }
        if (StringUtils.isEmpty(newName)){
            throw new BaseException("重命名不能为空");
        }
        if (StringUtils.isEmpty(parentPath)){
            throw new BaseException("父级路径不能为空");
        }
        if (!serverFileUtil.serverRename(filePath,newName,parentPath)){
            throw new BaseException("操作失败，可能同名文件已存在");
        }
    }

    @Override
    public void serverCopy(String filePath, String newName, String parentPath) {
        if (StringUtils.isEmpty(filePath)){
            throw new BaseException("源文件路径不能为空");
        }
        if (StringUtils.isEmpty(newName)){
            throw new BaseException("文件名不能为空");
        }
        if (StringUtils.isEmpty(parentPath)){
            throw new BaseException("父级路径不能为空");
        }
        serverFileUtil.copy(filePath,newName,parentPath);
    }

    private void checkFiles(List<MultipartFile> files) {
        if (files.size() == 0 || files.isEmpty()) {
            throw new BaseException("未选择文件，上传文件为空");
        }
    }

    private String getFileSize(long size) {
        if (size >= 1024 * 1024 * 1024) {
            return new Long(size / 1073741824L) + "G";
        } else if (size >= 1024 * 1024) {
            return new Long(size / 1048576L) + "M";
        } else if (size >= 1024) {
            return new Long(size / 1024) + "K";
        } else {
            return size + "B";
        }
    }


}
